<template>
	<!-- 音乐播放页面 -->
	<view class="play-page" :style="bgStyle">
		<view class="back" @click="goBack()">
			返回
		</view>
		<view class="bg">
		</view>
		<!-- 拨条 播放和不播放时两种样式 -->
		<view class="strip-box" :class="playState ? 'active' : ''">
			<image class="img" src="https://s3.music.126.net/mobile-new/img/needle-ip6.png?be4ebbeb6befadfcae75ce174e7db862=" mode=""></image>
		</view>
		<view class="content">
			<!-- 转盘图片 -->
			<view class="play-poster">
				<view class="poster-box" :class="playState?'play':'pause'">
					<image :src="curSongItem.picUrl" mode="widthFix" class="img"></image>
				</view>
			</view>
			<view class="bot">
				<view class="name">
					<text> {{curSongItem.name}} </text>
				</view>
				<!-- 上排的图标 -->
				<view class="tool-groups flex-box">
					<!-- 收藏 -->
					<view class="flex-item">
						<text class="iconfont">&#xe615;</text>
					</view>
					<!-- 下载 -->
					<view class="flex-item iconfont">
						&#xe60e;
					</view>
					<!-- 分享 -->
					<view class="flex-item iconfont">
						&#xe6ac;
					</view>
					<!-- 评论 -->
					<view class="flex-item iconfont">
						&#xe628;
					</view>
					<!-- 其它 -->
					<view class="flex-item iconfont">
						&#xe60f;
					</view>
				</view>
				<!-- 进度条 -->
				<view class="slider-bar flex-box">
					<!-- 开始时间 -->
					<view class="time" style="padding-left: 5rpx;">
						<!-- {{Math.floor(curPlayTime/60) }} : 
						{{Math.floor(curPlayTime%60)<10?"0"+Math.floor(curPlayTime%60):Math.floor(curPlayTime%60)}} -->
						<!--  开始时间 调用挂在全局的方法 --------------------------------------------- -->
						{{$pubFn.formatTime(curPlayTime)}}
					</view>
					<!-- 进度条 -->
					<slider 
						class="line flex-item" 
						:value="curPlayTime" 
						:max="playTime"
						@change="sliceChange"
						min="0" 
						block-size="15" 
						backgroundColor="rgba(255,255,255,.5)"   
						activeColor="rgba(255,255,255,.5)"
					/>
					<!-- 结束时间 -->
					<view class="time ">
						<!-- {{Math.floor(playTime/60) }} : 
						{{Math.floor(playTime%60)<10?"0"+Math.floor(playTime%60):Math.floor(playTime%60)}} -->
						{{$pubFn.formatTime(playTime)}}
					</view>
				</view>
				<!-- 下排图标 -->
				<view class="btn-groups flex-box">
					<!-- 播放模式 -->
					<view class="flex-item" @click="setPlayModel()">
						<view class="iconfont">
							{{playModel==0?'&#xe66c':playModel==1?'&#xe66b':'&#xe66d'}}
						</view>
					</view>
					<!-- 上一曲 -->
					<view class="flex-item" @click="prevPlay()">
						<view class="iconfont">
							&#xe78a
						</view>
					</view>
					<!-- 播放/暂停 -->
					<view class="play-btn" @click="play()">
						<view class="iconfont" >
							{{playState===1 ? '&#xe76a' : '&#xe638'}}
						</view>
					</view>
					<!-- 下一曲 -->
					<view class="flex-item" @click="nextPlay()">
						<view class="iconfont">
							&#xe7a5
						</view>
					</view>
					<!-- 菜单 -->
					<view class="flex-item iconfont">
							&#xe634
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	// 获取指定范围的随机数方法
	function RandomNumBoth(Min,Max){
	      var Range = Max - Min;
	      var Rand = Math.random();
	      var num = Min + Math.round(Rand * Range); //四舍五入
	      return Math.floor(num);
	}
	
	import { mapState,mapMutations } from "vuex"
	import { apiGetSongUrl,apiGetSongDetail } from "@/apis/index.js"
	let innerAudioContext = null
	
	export default {
		data() {
			return {
				playState:0,		//播放状态   1播放  0暂停
				curPlayIndex:0,		//当前播放的索引
				curPlayTime:0,		//当前播放时间
				curId:'',
				curSongItem:{},		//当前音乐播放对象
				playTime:0,			//文件音乐播放时长  进度条用到
				audioList:[],		//音乐列表
				playModel:0,		//播放模式  0-列表循环 1-随机 2-单曲循环
			}
		},
		computed:{
			...mapState(['playList']),
			// 设置滤镜背景
			bgStyle(){
				return `background-image:url(${this.curSongItem.picUrl||''})`;
			},
		},
		mounted() {
			this.playInit()
			this.curPlayIndex = 0
			// 从vuex拿到音乐列表
			this.audioList = this.playList
			// 从浏览器缓存中拿出之前是什么播放模式
			this.playModel = uni.getStorageSync("playModel")
		},
		methods: {
			...mapMutations(["storePlayList"]),
			// 返回按钮
			goBack(){
				console.log("返回");
				uni.navigateBack()
			},
			// 切换播放模式
			setPlayModel(){
				this.playModel = this.playModel>1 ? 0 : this.playModel+1
				// 播放模式记录在缓存
				uni.setStorageSync("playModel", this.playModel)
				uni.showToast({
					icon:"none",
					title:['已切换到列表循环','已切换到随机播放','已切换到单曲循环'][this.playModel]
				})
			},
			// 上一首按钮
			prevPlay(){
				if(this.curPlayIndex>0){
					this.curPlayIndex--
				}else{
					this.curPlayIndex = this.playList.length - 1
				}
				this.playInit()
			},
			// 下一首按钮
			nextPlay(){
				// 通过索引切歌 如果到了最后一首就切换回第一首歌
				if(this.curPlayIndex<this.playList.length-1){  
					this.curPlayIndex++
				}else{
					this.curPlayIndex = 0
				}
				this.playInit()
			},
			// 拖动进度条到指定位置播放
			sliceChange(e){
				// e里面有拖动的数据 
				this.curPlayTime = e.detail.value 
				innerAudioContext.seek(e.detail.value)
			},
			// 播放按钮
			play(){
				if(this.playState === 1 ){  	//当前是播放状态,点击切换成暂停
					// 暂停
					innerAudioContext.pause()
				}else{						//否则当前是暂停状态,点击切换成播放
					// 播放
					innerAudioContext.play()
				}
			},
			/*
				设置播放的文件-----------------------------------
					uni.createInnerAudioContext   	  (H5)
					uni.getBackgroundAudioManager	  (非H5)
			*/ 
			setDudio(){
				// 若存在之前的实例侧取消
				if(innerAudioContext){
					// 处理兼容问题,H5才使用这个方法 
					// #ifdef H5
					innerAudioContext.destroy()
					// #endif
					innerAudioContext = null
				}
				
				// 创建实例 H5中
				// #ifdef H5
				innerAudioContext = uni.createInnerAudioContext()
				// #endif
				
				// 创建实例 非H5中
				// #ifndef H5
				innerAudioContext = uni.getBackgroundAudioManager()
				innerAudioContext.title = this.curSongItem.name
				innerAudioContext.singer = this.curSongItem.singer
				innerAudioContext.coverImgUrl = this.curSongItem.picUrl
				// #endif
				
				innerAudioContext.src = this.curSongItem.src	//音乐连接	
				innerAudioContext.autoplay = true     			//自动播放
				
				// 获取音乐时长 可能读的时候innerAudioContext还没准备好  所以不停地去读时间
				let timer = setInterval(()=>{
					this.playTime = Math.floor( innerAudioContext.duration || 0)
					//如果播放时间存在,表明音乐已经在播放,侧不再去读取
					if(this.playTime){  
						clearInterval(timer)
					}
				},100)
				
				// 监听事件 (自带)
				innerAudioContext.onPlay(()=>{  	//播放事件
					this.playState = 1
				})
				innerAudioContext.onPause(()=>{		//暂停事件
					this.playState = 0
				})
				innerAudioContext.onEnded(()=>{		//结束事件,根据播放模式播放下一首
					console.log("音乐结束,下一首");
					//列表循环,调用下一首按钮的方法
					if(this.playModel==0){  		
						this.nextPlay()
					}else if(this.playModel==1){//随机播放,调用函数获取指定范围的随机数	
						this.curPlayIndex = RandomNumBoth(0,this.playList.length)
						this.playInit()
					}else{						//单曲循环
						this.playInit()
					}
				})
				// 监听进度条
				innerAudioContext.onTimeUpdate(()=>{ //得到当前播放时间
					this.curPlayTime = Math.floor(innerAudioContext.currentTime)
				})
			},
			// 初始化
			playInit(){
				const curVudio = this.playList[this.curPlayIndex]
				this.curId = curVudio.id
				this.curPlayTime = 0
				// 拿到这首歌
				this.getData()
			},
			// 获取音乐文件url地址和详情,同时调用多个接口使用Promise.all-----------------
			async getData(){
				let [detail, url] = await Promise.all([
					// 接口1:根据id获取音乐详情
					apiGetSongDetail({ids:this.curId}).then(res=>{
						// 处理数据
						var songs = res.data.songs[0]
						var singer = songs.ar.map(item =>{
							return item.name
						})[0]
						return {   //	返回处理好的数据
							name:songs.al.name,
							picUrl:songs.al.picUrl,
							singer:singer
						}
					}),
					// 接口2:根据id,获取歌曲的URL
					apiGetSongUrl({id:this.curId}).then(res => {
						let src = res.data.data[0].url
						if(!src){
							uni.showToast({
								title:"播放地址不存在!"
							})
							return
						}
						return {
							src:res.data.data[0].url
						}
					})
				]);
				this.curSongItem = {...detail,...url}
				if(url){  		//如果有音乐连接,进来就设置播放的文件
					this.setDudio()
				}else{
					uni.showToast({
						title:"url不存在!"
					})
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	.bg {
		position: fixed;
		z-index: 0;
		right: 0;
		left: 0;
		height: 100%;
		width: 100%;
		filter: blur(40rpx);
		background: inherit;
		z-index:-1;
		transform:scale(1.5);
	}
	.play-page {
		position: fixed;
		right: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-position: center center;
		background-repeat: no-repeat;
		background-size: cover;
	}
	.slider-bar {
		color: rgba(255,255,255, .6);
		padding: 20rpx 0;
		justify-content: space-between;
		.line {
			margin: 0;
			border-radius: 2rpx;
		}
		.time{
			height: 36rpx;
			width: 100rpx;
			margin-right: 10rpx;
			font-size: 36rpx;
			line-height: 76rpx;
			transform: scale(0.5) translateY(-50%);
		}
	}
	.strip-box{
		position: absolute;
		width:100%;
		top:142rpx;
		/* #ifdef H5 */
		top:0rpx;
		/* #endif */
		height: 329rpx;
		z-index: 100;
		transform: rotate(-30deg);
		transform-origin: center 0;
		transition: transform 0.3s;
		&:before{
			position: absolute;
			content: "";
			top:-20rpx;
			left: 350rpx;
			width: 48rpx;
			height: 48rpx;
			border-radius: 48rpx;
			background: #fff;
			z-index: 100;
		}
		&.active{
			transform: rotate(0deg);
		}
		.img{
			width: 220rpx;
			height: 330rpx;
			margin-left: 340rpx;
		}
	}
	.play-poster {
		margin: 310rpx auto 0;
		/* #ifdef H5 */
		margin-top: 130rpx;
		/* #endif */
		.poster-box{
			display: flex;
			width: 616rpx;
			height:616rpx;
			margin: 0 auto;
			background: url(https://s3.music.126.net/mobile-new/img/disc-ip6.png?69796123ad7cfe95781ea38aac8f2d48=) center center no-repeat;
			background-size:100%;
			align-items: center;
			justify-content: center;
			animation: circling 20s linear infinite;
			&.pause{
				animation-play-state: paused;
			}
		}
		.img {
			display: block;
			margin: 0 auto;
			width: 382rpx;
			height: 382rpx;
			border: solid 16rpx rgba(0, 0, 0, .15);
			border-radius: 50%;
		}
	}
	@-webkit-keyframes circling {
		0% {
			transform: rotate(0);
		}
		100% {
			transform: rotate(1turn);
		}
	}
	.btn-groups {
		align-items: center;
		text-align: center;
		.iconfont{
			font-size: 40rpx;
		}
		.play-btn{
			position: relative;
			width:120rpx;
			height:120rpx;
			line-height: 120rpx;
			&:before{
				position:absolute;
				content:"";
				width:240rpx;
				height:240rpx;
				border:1px solid #fff;
				border-radius: 240rpx;
				transform: scale(0.5) translate(-100%,-50%);
				z-index: -1;
			}
		}
	}
	.tool-groups {
		margin-bottom: 20rpx;
		text-align: center;
		.iconfont{
			font-size: 40rpx;
		}
	}
	.title-bar {
		position: fixed;
		top:0;
		width:100%;
		height: 44px;
		margin-top: 20px;
		text-align: center;
		line-height: 44px;
		color:#fff;
		z-index: 100;
		.name {
			line-height: 50rpx;
			font-size: 28rpx;
		}
		.author {
			line-height: 1;
			font-size: 24rpx;
			color: rgba(255,255,255,.8);
		}
		.iconfont{
			width:110rpx;
			font-size: 44rpx;
		}
	}
	
	.content {
		position: fixed;
		z-index: 1;
		right: 0;
		left: 0;
		height: 100%;
		width: 100%;
		color: #FFFDEF;
		.bot {
			position: fixed;
			bottom: 40rpx;
			left: 0;
			width: 100%;
			padding: 0 26rpx;
		}
	}
	.album-list {
		position: absolute;
		bottom:0;
		background: #fff;
		border-radius: 36rpx 36rpx 0 0;
		z-index: 100;
		transition: transform 0.3s;
		transform: translateY(100%);
		&.active{
			transform: translateY(0);
		}
		.list{
			height:500rpx;
			overflow-y: scroll;
		}
		.tit-bar{
			padding:10rpx;
			justify-content: space-between;
			.iconfont{
				margin-left: 16rpx;
				margin-right: 16rpx;
				font-size: 40rpx;
			}
			.play{
				line-height: 80rpx;
				color:#252621;
				font-weight: 600;
				font-size: 32rpx;
			}
			.collect{
				width:228rpx;
				height:80rpx;
				text-align: center;
				line-height: 80rpx;
				border-radius: 80rpx;
				color:#fff;
				background: #fb2b21;
			}
		}
		.item {
			align-items: center;
			height: 120rpx;
		}
		.con {
			padding-right: 40rpx;
			align-items: center;
			justify-content: space-between;
		}
		.num {
			width: 84rpx;
			text-align: center;
			line-height: 120rpx;
			color: #999;
			font-size: 24rpx;
			&.on {
				color: #ff3a3a;
			}
		}
		.tit {
			margin-right: 20rpx;
			color: #333;
			line-height: 48rpx;
			font-size: 32rpx;
		}
		.count {
			margin-right: 20rpx;
			color: #ccc;
			line-height: 48rpx;
			font-size: 24rpx;
			transform: scale(0.84);
		}
		.icon {
			width: 56rpx;
			height: 20rpx;
		}
		.desc {
			color: #999;
			font-size: 24rpx;
			line-height: 40rpx;
		}
		.close{
			position: relative;
			height: 50px;
			line-height: 50px;
			text-align: center;
			&:before{
				position:absolute;
				content:"";
				top:0;
				left:0;
				width:100%;
				border-top:1px solid #ddd;
				transform: scaleY(0.5);
			}
		}
	}
	.name{
		display: flex;
		justify-content: center;
		align-items: center;
		margin-bottom: 50rpx;
		height: 40rpx;
		font-size: 38rpx;
	}
	.back{
		margin: 15rpx;
		height: 30rpx;
		width: 60rpx;
		color: #FFFDEF;
		z-index: 99999;
	}
</style>
